package com.ynunicom.dc.dingdingcontractapp.controller.exceptioncontroller;

import com.ynunicom.dc.dingdingcontractapp.dto.ResponseDto;
import com.ynunicom.dc.dingdingcontractapp.dto.exception.*;
import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
import org.flowable.engine.RuntimeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.net.UnknownHostException;
import java.util.Arrays;

/**
 * @author: jinye.Bai
 * @date: 2020/5/22 17:25
 */
@RestControllerAdvice
@Slf4j
public class ExceptionController {

    @Autowired
    RuntimeService runtimeService;

    @ResponseStatus(HttpStatus.BAD_GATEWAY)
    @ExceptionHandler(UserNotFoundException.class)
    public ResponseDto userNotFoundException(UserNotFoundException e){
        log.error(e.getMsg());
        return ResponseDto.failed(e.getMsg());
    }

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(FlowableObjectNotFoundException.class)
    public ResponseDto flowableObjectNotFoundException(FlowableObjectNotFoundException e){
        log.error(e.getMessage());
        return ResponseDto.failed(e.getMessage());
    }


    @ResponseStatus(HttpStatus.SERVICE_UNAVAILABLE)
    @ExceptionHandler(RsponseEmptyException.class)
    public ResponseDto rsponseEmptyException(RsponseEmptyException e){
        log.error(e.getMessage());
        runtimeService.deleteProcessInstance(e.getProcessInstanceId(),e.getMessage());
        return ResponseDto.failed(e.getMessage());
    }

    @ResponseStatus(HttpStatus.NO_CONTENT)
    @ExceptionHandler(NullPointerException.class)
    public ResponseDto nullPointerException(NullPointerException e){
        log.error(Arrays.toString(e.getStackTrace()));
        return ResponseDto.failed("出现了意料之外的空指针异常");
    }

    @ResponseStatus(HttpStatus.SERVICE_UNAVAILABLE)
    @ExceptionHandler(UnknownHostException.class)
    public ResponseDto unknowHostException(UnknownHostException e){
        String msg = "钉钉服务器连接失败";
        log.info(msg);
        return ResponseDto.failed(msg);
    }

    @ResponseStatus(HttpStatus.BAD_GATEWAY)
    @ExceptionHandler(TokenNullException.class)
    public ResponseDto tokenNullException(TokenNullException e){
        log.error(e.getMessage());
        return ResponseDto.failed(e.getCode(),e.getMessage());
    }

    @ResponseStatus(HttpStatus.BAD_GATEWAY)
    @ExceptionHandler(GetUserIdException.class)
    public ResponseDto getUserIdException(GetUserIdException e){
        log.error(e.getMessage());
        return ResponseDto.failed(e.getCode(),e.getMessage());
    }

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseDto validException(MethodArgumentNotValidException e){
        StringBuilder errorMessage = new StringBuilder(e.getBindingResult().getFieldErrors().size()*16);
        for (FieldError fe:e.getBindingResult().getFieldErrors()) {
            errorMessage.append(fe.getField());
            errorMessage.append(":");
            errorMessage.append(fe.getDefaultMessage());
            errorMessage.append("#");
        }
        return ResponseDto.failed(errorMessage.toString());
    }

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public ResponseDto missngRequestParamException(MissingServletRequestParameterException e){
        log.error(e.getMessage());
        return ResponseDto.failed(e.getMessage());
    }

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public ResponseDto httpMessageNotReadableException(HttpMessageNotReadableException e){
        log.error(e.getMessage());
        return ResponseDto.failed(e.getMessage());
    }

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(ParamNullException.class)
    public ResponseDto paramNullException(ParamNullException e){
        log.error(e.getMessage());
        return ResponseDto.failed(e.getMessage());
    }

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(FileNotFoundException.class)
    public ResponseDto fileNotFoundException(FileNotFoundException e){
        log.error(String.format("[%S]文件没有找到",e.getFileName()));
        return ResponseDto.failed(String.format("[%S]文件没有找到",e.getFileName()));
    }


}
